#import "FlutterGromoreAdsPlugin.h"
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
#import "FGMNativeViewFactory.h"

#ifdef DEBUG
// #import <BUAdTestMeasurement/BUAdTestMeasurement.h>
#endif

@implementation FlutterGromoreAdsPlugin

// 单例方便后面复用
+ (instancetype)shared {
    static FlutterGromoreAdsPlugin *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// AdBannerView
NSString *const kGMAdBannerViewId=@"flutter_gromore_ads_banner";
// AdFeedView
NSString *const kGMAdFeedViewId=@"flutter_gromore_ads_feed";
// AdDrawFeedView
NSString *const kGMAdDrawFeedViewId=@"flutter_gromore_ads_draw_feed";

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* methodChannel = [FlutterMethodChannel
                                     methodChannelWithName:@"flutter_gromore_ads"
                                     binaryMessenger:[registrar messenger]];
    
    FlutterEventChannel* eventChannel=[FlutterEventChannel eventChannelWithName:@"flutter_gromore_ads_event" binaryMessenger:[registrar messenger]];
    
    FlutterGromoreAdsPlugin* instance = [FlutterGromoreAdsPlugin shared];
    [registrar addMethodCallDelegate:instance channel:methodChannel];
    [eventChannel setStreamHandler:instance];

    // 注册平台View 工厂
    FGMNativeViewFactory *bannerFactory=[[FGMNativeViewFactory alloc] initWithViewName:kGMAdBannerViewId withMessenger:registrar.messenger withPlugin:instance];
    
    FGMNativeViewFactory *feedFactory=[[FGMNativeViewFactory alloc] initWithViewName:kGMAdFeedViewId withMessenger:registrar.messenger withPlugin:instance];
    
    FGMNativeViewFactory *drawFeedFactory=[[FGMNativeViewFactory alloc] initWithViewName:kGMAdDrawFeedViewId withMessenger:registrar.messenger withPlugin:instance];
    
    
    // 注册 Banner View
    [registrar registerViewFactory:bannerFactory withId:kGMAdBannerViewId];
    // 注册 Feed View
    [registrar registerViewFactory:feedFactory withId:kGMAdFeedViewId];
    // 注册 Draw 信息流 View
    [registrar registerViewFactory:drawFeedFactory withId:kGMAdDrawFeedViewId];
    
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSString *methodStr=call.method;
    if ([@"getPlatformVersion" isEqualToString:methodStr]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
    }else if ([@"requestIDFA" isEqualToString:methodStr]) {
        [self requestIDFA:call result:result];
    }else if ([@"initAd" isEqualToString:methodStr]){
        [self initAd:call result:result];
    }else if ([@"preload" isEqualToString:methodStr]){
        [self preload:call result:result];
    }else if ([@"showSplashAd" isEqualToString:methodStr]) {
        [self showSplashAd:call result:result];
    }else if ([@"showInterstitialAd" isEqualToString:methodStr]) {
        [self showInterstitialAd:call result:result];
    }else if ([@"showRewardVideoAd" isEqualToString:methodStr]) {
        [self showRewardVideoAd:call result:result];
    }else if ([@"loadFeedAd" isEqualToString:methodStr]){
        [self loadFeedAd:call result:result];
    }else if ([@"clearFeedAd" isEqualToString:methodStr]){
        [self clearFeedAd:call result:result];
    }else if ([@"launchTestTools" isEqualToString:methodStr]){
        [self launchTestTools:call result:result];
    }else {
        result(FlutterMethodNotImplemented);
    }
}

// 请求 IDFA
- (void) requestIDFA:(FlutterMethodCall*) call result:(FlutterResult) result{
    if (@available(iOS 14, *)) {
        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
            BOOL requestResult=status == ATTrackingManagerAuthorizationStatusAuthorized;
            NSLog(@"FlutterGromoreAdsPlugin requestIDFA:%@",requestResult?@"YES":@"NO");
            result(@(requestResult));
        }];
    } else {
        result(@(YES));
    }
}

// 初始化广告
- (void) initAd:(FlutterMethodCall*) call result:(FlutterResult) result{
    if (self.adInit) {
        result(@(YES));
        NSLog(@"FlutterGromoreAdsPlugin initAd 已初始化过");
        return;
    }
    NSString *appId=call.arguments[@"appId"];
    NSString *config=call.arguments[@"config"];
    BOOL useMediation=[call.arguments[@"useMediation"] boolValue];
    int limitPersonalAds=[call.arguments[@"limitPersonalAds"] intValue];
    int themeStatus=[call.arguments[@"themeStatus"] intValue];
    BUAdSDKConfiguration *configuration = [BUAdSDKConfiguration configuration];
    // 是否开启调试
    #ifdef DEBUG
        configuration.debugLog = @(1);
    #endif
    // 配置 appid 和使用聚合
    configuration.appID = appId;
    configuration.useMediation = useMediation;
    configuration.themeStatus = [NSNumber numberWithInt:themeStatus];
    // 隐私合规
    configuration.mediation.limitPersonalAds = @(limitPersonalAds);
    configuration.mediation.limitProgrammaticAds = @(limitPersonalAds);
    configuration.mediation.forbiddenIDFA = @(limitPersonalAds);
    // 提前导入配置
    if (![config isKindOfClass:[NSNull class]] && [config length]!=0) {
        configuration.mediation.advanceSDKConfigPath = [[NSBundle mainBundle]pathForResource:config ofType:@"json"];
    }
    // 初始化
    [BUAdSDKManager startWithAsyncCompletionHandler:^(BOOL success, NSError *error) {
        if (success) {
            result(@(YES));
            self.adInit = true;
        } else {
            result(@(NO));
            NSLog(@"FlutterGromoreAdsPlugin initAd error:%@",error.description);
            self.adInit = false;
        }
    }];
}

// 预加载
- (void) preload:(FlutterMethodCall*) call result:(FlutterResult) result{
    NSArray *rewardPosids= call.arguments[@"rewardPosids"];
    NSArray *insertPosids= call.arguments[@"insertPosids"];
    int concurrent=[call.arguments[@"concurrent"] intValue];
    int interval=[call.arguments[@"interval"] intValue];
    NSString *customData = call.arguments[@"customData"] ;
    NSString *userId = call.arguments[@"userId"];
    // 广告集合
    NSMutableArray *infos=[[NSMutableArray alloc] init];
    // 加载激励视频
    for (NSString *posid in rewardPosids) {
        BUAdSlot *adslot = [[BUAdSlot alloc]init];
        adslot.ID = posid;
        BURewardedVideoModel *model = [[BURewardedVideoModel alloc] init];
        model.userId = userId;
        model.extra = customData;
        BUNativeExpressRewardedVideoAd *rewardVideoAd = [[BUNativeExpressRewardedVideoAd alloc] initWithSlot:adslot rewardedVideoModel:model];
        [infos addObject:rewardVideoAd];
    }
    // 加载插屏
    for (NSString *posid in insertPosids) {
        BUNativeExpressFullscreenVideoAd *fullscreenAd= [[BUNativeExpressFullscreenVideoAd alloc] initWithSlotID:posid];
        [infos addObject:fullscreenAd];
    }
    // 预加载
    [BUAdSDKManager.mediation preloadAdsWithInfos:infos andInterval:interval andConcurrent:concurrent];
}

// 开屏广告
- (void) showSplashAd:(FlutterMethodCall*) call result:(FlutterResult) result{
    if (self.sad!=nil&&self.sad.isDisplay) {
        result(@(NO));
        NSLog(@"%s-error:%@", __func__, @"广告展示中，无法再次展示");
        return;
    }
    // 是否展示已预加载的广告
    BOOL preload=[call.arguments[@"preload"] boolValue];
    // 如果已预加载则直接展示
    if (self.sad!=nil&&self.sad.isLoaded&&preload) {
        [self.sad showSplashPage];
    }else{
        // 重新加载展示广告
        self.sad=[[FGMSplashPage alloc] init];
        [self.sad showAd:call eventSink:self.eventSink];
    }
    result(@(YES));
    
}

// 插屏广告
- (void) showInterstitialAd:(FlutterMethodCall *)call result:(FlutterResult) result{
    self.iad=[[FGMInterstitialPage alloc] init];
    [self.iad showAd:call eventSink:self.eventSink];
    result(@(YES));
}

// 激励视频广告
- (void) showRewardVideoAd:(FlutterMethodCall *)call result:(FlutterResult) result{
    self.rvad=[[FGMRewardVideoPage alloc] init];
    [self.rvad showAd:call eventSink:self.eventSink];
    result(@(YES));
}

// 加载信息流广告
- (void) loadFeedAd:(FlutterMethodCall*) call result:(FlutterResult) result{
    self.fad=[[FGMFeedAdLoad alloc] init];
    [self.fad loadFeedAdList:call result:result eventSink:self.eventSink];
}

// 清除信息流广告
- (void) clearFeedAd:(FlutterMethodCall*) call result:(FlutterResult) result{
    NSArray *list= call.arguments[@"list"];
    for (NSNumber *ad in list) {
        [FGMFeedAdManager.share removeAd:ad];
    }
    result(@(YES));
}

// 清除信息流广告
- (void) launchTestTools:(FlutterMethodCall*) call result:(FlutterResult) result{
    // #ifdef DEBUG
    //     [BUAdTestMeasurementConfiguration configuration].debugMode = YES;
    //     [BUAdTestMeasurementManager showTestMeasurementWithController:[UIApplication sharedApplication]. keyWindow.rootViewController];
    // #endif
    result(@(YES));
}

#pragma mark - FlutterStreamHandler

- (FlutterError *)onCancelWithArguments:(id)arguments{
    self.eventSink = nil;
    return nil;
}
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events{
    self.eventSink = events;
    return nil;
}

- (void)addEvent:(NSObject *) event{
    if(self.eventSink){
        self.eventSink(event);
    }
}

- (void)sendEvent:(FGMAdEvent *)event{
    if(event){
        [self addEvent:event.toMap];
    }
}

@end
